package cn.piggy.gateway.core.socket.handler;

import cn.piggy.gateway.core.config.ConfigHelper;
import cn.piggy.gateway.core.executor.result.SessionResult;
import cn.piggy.gateway.core.proxy.MyGenericReference;
import cn.piggy.gateway.core.session.GatewaySession;
import cn.piggy.gateway.core.session.simple.SimpleGatewaySessionFactory;
import cn.piggy.gateway.core.socket.common.AgreementConstant;
import cn.piggy.gateway.core.socket.common.GatewayResult;
import cn.piggy.gateway.core.socket.parser.RequestParser;
import cn.piggy.gateway.core.socket.parser.ResponseParser;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;


public class RequestForwardHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    private final Logger logger = LoggerFactory.getLogger(RequestForwardHandler.class);

    private final SimpleGatewaySessionFactory gatewaySessionFactory;

    public RequestForwardHandler(SimpleGatewaySessionFactory gatewaySessionFactory) {
        this.gatewaySessionFactory = gatewaySessionFactory;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
        Channel channel = ctx.channel();
        logger.info("网关接收请求【消息】 uri：{} method：{}", request.uri(), request.method());
        try {
            // 1. 解析请求参数
            RequestParser parser = new RequestParser(request);
            String uri = parser.getUri();
            if (null == uri)
                return;
            Map<String, Object> args = parser.parse();

            // 2. 调用会话服务
            GatewaySession gatewaySession = gatewaySessionFactory.openSession(uri);
            // 3.
            ConfigHelper configuration = gatewaySessionFactory.getConfigHelper();
            // 3. 生成代理对象
//            MyGenericReference reference = configuration.getGenericReferenceCjLib(uri, gatewaySession);
            MyGenericReference reference = configuration.getGenericReferenceJdk(uri, gatewaySession);
            SessionResult result = reference.$invoke(args);
            // 3. 封装返回结果
            String code = result.getCode();
            Object data = result.getData();
            GatewayResult gatewayResult = "0000".equals(code) ? GatewayResult.buildSuccess(data) : GatewayResult.buildError(code, "网关协议调用失败 -> " + data);
            gatewayResult.setNode(node());
            DefaultFullHttpResponse response = new ResponseParser().parse(gatewayResult);
            channel.writeAndFlush(response);
        } catch (Exception e) {
            e.printStackTrace();
            // 4. 封装返回结果
            GatewayResult gatewayResult = GatewayResult.buildError(AgreementConstant.ResponseCode._502.getCode(), "网关协议调用失败 -> " + e.getMessage());
            gatewayResult.setNode(node());
            DefaultFullHttpResponse response = new ResponseParser().parse(gatewayResult);
            channel.writeAndFlush(response);
        }
    }

    private String node(){
        return gatewaySessionFactory.getConfigHelper().getHostName() + ":" + gatewaySessionFactory.getConfigHelper().getPort();
    }
}
